#ifndef UTILS_UTILS_H_
#define UTILS_UTILS_H_

#include <vector>
#include <iostream>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <list>
#include <math.h>
#include "numeric"

template <typename T>
void printVec(std::string func_name, const std::vector<T> &vec) {
    std::cout << "[" << func_name << "]: ";
    for (size_t i = 0; i < vec.size(); i++) {
        std::cout << vec[i] << " ";
    }
    std::cout << std::endl;
}

template <typename T>
void printVec(std::string func_name, const std::list<T> &vec) {
    std::cout << "[" << func_name << "]: ";
    for (auto i = vec.begin(); i != vec.end(); i++) {
        std::cout << *i << " ";
    }
    std::cout << std::endl;
}

template <typename T>
void printVec(std::string func_name, const std::vector<std::vector<T>> &vec) {
    std::cout << "[" << func_name << "]: " << std::endl;
    for (size_t i = 0; i < vec.size(); i++) {
        for (size_t j = 0; j < vec[i].size(); j++) {
            std::cout << vec[i][j] << " ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

template <typename T1, typename T2>
void printVec(std::string func_name, const std::vector<std::pair<T1, T2>> &vec) {
  std::cout << "[" << func_name << "]: " << std::endl;
  for (size_t i = 0; i < vec.size(); i++) {
    std::cout << vec[i].first << " " << vec[i].second << std::endl;
  }
  std::cout << std::endl;
}

void swap(std::vector<int> &input, int i, int j);

bool isFloatEqual(double x, double y);

#endif
